package com.haonan.springboot_exercise.service.impl;

import com.haonan.springboot_exercise.bean.Email;
import com.haonan.springboot_exercise.bean.pojo.MsgResult;
import com.haonan.springboot_exercise.bean.pojo.ReadableMail;
import com.haonan.springboot_exercise.bean.pojo.Result;
import com.haonan.springboot_exercise.dao.PopServerDao;
import com.haonan.springboot_exercise.dao.SmtpServerDao;
import com.haonan.springboot_exercise.dao.UserDao;
import com.haonan.springboot_exercise.netty.client.PopClient;
import com.haonan.springboot_exercise.netty.client.SmtpClient;
import com.haonan.springboot_exercise.bean.pojo.MyMailMessage;
import com.haonan.springboot_exercise.service.MailService;
import com.haonan.springboot_exercise.service.SmtpServerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 通过调用SMTP/POP3客户端与服务端通信，服务端进行处理后传给客户端相关message，最终提供用户需要的服务
 * @author haonan
 */
@Component
public class MailServiceImpl implements MailService {
    @Autowired
    SmtpServerDao smtpServerDao;
    @Autowired
    PopServerDao popServerDao;
    @Autowired
    SmtpServerService smtpServerService;
    @Autowired
    UserDao userDao;

    private final String IP = "127.0.0.1";

    @Override
    public MsgResult sendMyMail(MyMailMessage myMailMessage) throws Exception {
        SmtpClient smtpClient = new SmtpClient();
        smtpClient.run();
        smtpClient.getSmtpClientHandler().sendDataToServer(smtpClient.getChannel(), "HELO:" + smtpServerDao.getSmtpDomain(IP));

        int waitTime = 50;
        // 如果通道里得到的状态码在300以下，即正常的状态码
        // 那么就可以继续发消息
        // 发件人
        while (waitTime <= 500 && smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() != 250){
            Thread.sleep(waitTime);
            waitTime += 50;
        }
        if (smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() == 250) {
            smtpClient.getSmtpClientHandler().sendDataToServer(smtpClient.getChannel(), "MAIL:" + myMailMessage.getFrom());
        }
        // 收件人
        while (waitTime <= 500 && smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() != 251){
            Thread.sleep(waitTime);
            waitTime += 50;
        }
        if (smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() == 251) {
            smtpClient.getSmtpClientHandler().sendDataToServer(smtpClient.getChannel(), "RCPT:" + Arrays.toString(myMailMessage.getTo()));
        }
        // 主题
        while (waitTime <= 500 && smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() != 252){
            Thread.sleep(waitTime);
            waitTime += 50;
        }
        if(smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() == 252){
            smtpClient.getSmtpClientHandler().sendDataToServer(smtpClient.getChannel(), "SUBJ:" + myMailMessage.getSubject());
        }
        // 时间
        while (waitTime <= 500 && smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() != 253){
            Thread.sleep(waitTime);
            waitTime += 50;
        }
        if(smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() == 253){
            smtpClient.getSmtpClientHandler().sendDataToServer(smtpClient.getChannel(), "TIME:" + myMailMessage.getSent_time());
        }
        // 正文
        while (waitTime <= 500 && smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() != 254){
            Thread.sleep(waitTime);
            waitTime += 50;
        }
        if(smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() == 254){
            smtpClient.getSmtpClientHandler().sendDataToServer(smtpClient.getChannel(), "TEXT:" + myMailMessage.getText());
        }
        // 返回
        while (waitTime <= 500 && smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() != 300){
            Thread.sleep(waitTime);
            waitTime += 50;
        }
        if(smtpClient.getSmtpClientHandler().getMsgResultFromServer().getCode() == 300){
            smtpServerService.storeMails(myMailMessage);
        }
        return smtpClient.getSmtpClientHandler().getMsgResultFromServer();
    }

    @Override
    public List<ReadableMail> getInbox(String username) throws InterruptedException {
        // 该用户收到的邮件id的集合
        List<Integer> emailIdList = popServerDao.getAllEmailIdFromUser(username);
        // 可视邮件的集合
        List<ReadableMail> readableMailList = new ArrayList<>();
        PopClient popClient = new PopClient();
        popClient.run();
        popClient.getChannel().writeAndFlush("LIST:" + emailIdList.toString());

        int waitTime = 50;
        // 返回
        while (waitTime <= 500 && popClient.getPopClientHandler().getMsgResultFromServer().getCode() != 250){
            Thread.sleep(waitTime);
            waitTime += 50;
        }
        // 如果不行，就返回空
        if(popClient.getPopClientHandler().getMsgResultFromServer().getCode() != 250){
            return new ArrayList<>();
        }
        // 如果正常
        List<Email> emailList = popServerDao.getAllEmailFromUser(username);
        for (Email email : emailList) {
            readableMailList.add(new ReadableMail(email));
        }
        System.out.println(readableMailList);
        return readableMailList;
    }

    @Override
    public Result deleteEmail(List<Integer> emailIdList) {
        for (Integer email_id : emailIdList) {
            popServerDao.deleteEmailById(email_id);
        }
        return Result.succ("删除成功");
    }

    /**
     * 进入发件箱
     * 先从Dao层获取List<Email>，然后转换成List<ReadableMail>
     * @param user_name 用户名
     * @return （前端可读邮件的集合）
     * @throws InterruptedException
     */
    @Override
    public List<ReadableMail> getOutbox(String user_name) throws InterruptedException {
        List<Email> emailList = userDao.getOutbox(user_name);
        List<ReadableMail> readableMailList = new ArrayList<>();
        for (Email email : emailList) {
            readableMailList.add(new ReadableMail(email));
        }
        return readableMailList;
    }
}
